package com.matrix.review.service.impl;

import com.matrix.api.merchant.MerchantApi;
import com.matrix.api.product.ProductApi;
import com.matrix.api.review.dto.ShopAvgRatingDTO;
import com.matrix.review.entity.Review;
import com.matrix.review.mapper.ReviewItemMapper;
import com.matrix.review.mapper.ReviewMapper;
import com.matrix.review.service.ReviewStatService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.rpc.RpcException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author 有点甜
 * @since 2025/7/29
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ReviewStatServiceImpl implements ReviewStatService {

    private final ReviewMapper reviewMapper;
    private final ReviewItemMapper reviewItemMapper;

    @DubboReference(check = false)
    private MerchantApi merchantApi;
    @DubboReference(check = false)
    private ProductApi productApi;

    @Override
    @Transactional(readOnly = true)
    public void updateShopAndProductRating(Long reviewId) {
        log.info("开始处理评价统计任务, reviewId: {}", reviewId);
        Review review = reviewMapper.selectById(reviewId);
        if (review == null) {
            log.warn("评价 {} 不存在, 统计任务跳过。", reviewId);
            return;
        }
        updateShopRating(review.getShopId());
        updateProductsRating(review.getShopId());
    }

    private void updateShopRating(Long shopId) {
        ShopAvgRatingDTO avgRatings = reviewMapper.calculateAverageRatingsByShopId(shopId);
        if (avgRatings == null || avgRatings.getAvgOverall() == null) {
            log.warn("店铺 {} 没有任何评价, 无法更新平均分。", shopId);
            return;
        }
        Map<String, BigDecimal> ratingsToUpdate = new HashMap<>();
        ratingsToUpdate.put("overall", avgRatings.getAvgOverall().setScale(2, RoundingMode.HALF_UP));
        if (avgRatings.getAvgTaste() != null) {
            ratingsToUpdate.put("taste", avgRatings.getAvgTaste().setScale(2, RoundingMode.HALF_UP));
        }
        if (avgRatings.getAvgPackaging() != null) {
            ratingsToUpdate.put("packaging", avgRatings.getAvgPackaging().setScale(2, RoundingMode.HALF_UP));
        }
        try {
            merchantApi.updateShopRatings(shopId, ratingsToUpdate);
            log.info("成功更新店铺 {} 的评分。", shopId);
        } catch (RpcException e) {
            log.error("更新店铺评分失败, shopId: {}, RPC异常: {}", shopId, e.getMessage());
        }
    }

    private void updateProductsRating(Long shopId) {
        Map<Long, Map<String, Object>> productAvgRatings = reviewItemMapper.calculateAverageRatingsByShopId(shopId);
        if (productAvgRatings == null || productAvgRatings.isEmpty()) {
            log.info("店铺 {} 没有任何菜品被评价过, 无需更新菜品评分。", shopId);
            return;
        }
        Map<Long, BigDecimal> ratingsMap = productAvgRatings.entrySet().stream()
                .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        entry -> ((BigDecimal) entry.getValue().get("avg_rating")).setScale(2, RoundingMode.HALF_UP)
                ));
        try {
            productApi.batchUpdateProductRatings(ratingsMap);
            log.info("成功批量更新店铺 {} 的 {} 个菜品评分。", shopId, ratingsMap.size());
        } catch (RpcException e) {
            log.error("批量更新菜品评分失败, shopId: {}, RPC异常: {}", shopId, e.getMessage());
        }
    }
}